# -*- coding: utf-8 -*-
# @Time    : 2022/4/6 10:31
# @Author  : zyw
# @Email   : panda_kings@163.com
# @File    : jwt.py
# 生成token 及校验token
import traceback

import jwt
from datetime  import datetime, timedelta

from flask import current_app


# 1.生成token
def generate_token(payload, expiry, secret=None, algorithm='HS256'):
    """
    :param payload: dict 载荷,用户信息
    :param expiry: date 有效期
    :param secret: 每个项目的私钥, 要在配置文件中存放
    :param algorithm:  加密算法
    :return: token
    """
    # 私有变量,不对外提供
    # 生成有效期
    _payload = {
        'expiry': str(expiry) # 日期格式不能进行序列化
    }
    try:
        _payload.update(payload)
        if not secret:
            # 从配置文件的对象中读取
            secret = current_app.config.get('SECRET_KEY')
        # 把生成的token进行拼接,然后写入请求头
        token = jwt.encode(payload=_payload, key=secret,algorithm=algorithm)
        return token
    except Exception as e:
        error = traceback.format_exc()
        print('生成token 错误 :{}'.format(error))



# 2, 校验token
def verify_token(token,secret=None,algorithm='HS256'):
    """
    校验token
    :param token: 传递来的token
    :param secret: 每个项目的私钥, 要在配置文件中存放
    :param algorithm: 加密算法
    :return: payload 用户信息部分
    """
    if not secret:
        # 从配置文件中读取SECRET_KEY
        secret = current_app.config.get('SECRET_KEY')
    try:
        payload = jwt.decode(token, secret, algorithms=algorithm)
    except Exception as e:
        print("解密错误信息>>>", e)
        payload = None
    return payload


def _generate_token(account,user_id, refresh=True):
    """
    生成token 和 刷新token
    :return: token, refresh_token
    """
    secret = current_app.config.get('SECRET_KEY')
    # 定义过期时间: 2小时有效期
    expiry = datetime.utcnow() + timedelta(hours=2)

    # 生成Token
    token = 'JWT ' + generate_token({'account': account, 'user_id': user_id}, expiry, secret)
    if refresh:
        # 生成新token, 无感知刷新
        expiry = datetime.utcnow() + timedelta(days=15)
        # is_refresh作为更新token的信号
        refresh_token = 'JWT ' + generate_token({'account': account, 'user_id': user_id, 'is_refresh': True}, expiry,
                                                 secret)
    else:
        refresh_token = None
    return token, refresh_token
